<template>
  <i
    class="icon iconfont"
    :class="`icon-${iconClass}`"
    v-bind="$attrs"
    v-if="type.startsWith('i-')"
  />
  <el-icon v-else-if="type.startsWith('el-') && !!ElIconItem">
    <component class="icon" :is="ElIconItem" v-bind="$attrs" />
  </el-icon>
  <template v-else-if="type.startsWith('a-') && !!AntIconItem">
    <component class="icon" :is="AntIconItem" v-bind="$attrs" />
  </template>
  <span
    ref="iconRef"
    class="icon icon-picture"
    v-bind="$attrs"
    v-else-if="type.startsWith('p-')"
    :style="{
      backgroundImage: `url(${picture})`,
    }"
  >
    <span
      class="icon-picture__shader"
      :style="{
        filter: `drop-shadow(${fontSize} 0 0 ${color})`,
      }"
    />
  </span>
</template>

<script lang="ts">
import {
  camelize,
  capitalize,
  computed,
  defineComponent,
  ref,
  watchEffect,
} from 'vue'
import { ElIcon } from 'element-plus'
import * as ElIconList from '@element-plus/icons'
import * as AntCon from '@ant-design/icons-vue'

export default defineComponent({
  name: 'IconFont',
  components: { ElIcon },
  inheritAttrs: false,
  props: {
    type: {
      type: String,
      default: '',
    },
  },
  setup(props, { attrs }) {
    const iconRef = ref<HTMLSpanElement>()
    const iconClass = ref('')
    const picture = ref('')

    const ElIconItem = computed(() => {
      return (ElIconList as any)[iconClass.value] ?? null
    })
    const AntIconItem = computed(() => {
      return (AntCon as any)[iconClass.value] ?? null
    })

    const color = computed(() => {
      if (attrs.style) {
        return (attrs.style as any)?.color
      } else if (iconRef.value) {
        return getComputedStyle(iconRef.value).color
      } else {
        return 'var(--primary-color)'
      }
    })
    const fontSize = computed(() => {
      if (attrs.style) {
        return (attrs.style as any)?.fontSize
      } else if (iconRef.value) {
        return getComputedStyle(iconRef.value).fontSize
      } else {
        return '16px'
      }
    })

    watchEffect(() => {
      if (props.type?.startsWith('i-')) {
        // 如果是iconfont
        iconClass.value = props.type?.replace('i-', '')
      } else if (props.type?.startsWith('el-')) {
        // 如果是el-icon
        iconClass.value = capitalize(camelize(props.type?.replace('el-', '')))
      } else if (props.type?.startsWith('a-')) {
        // 如果是a-icon
        iconClass.value = capitalize(camelize(props.type?.replace('a-', '')))
      } else if (props.type?.startsWith('p-')) {
        // 如果是图片
        iconClass.value = props.type?.replace('p-', '')
        let url = `/src/assets/icons/${iconClass.value}.webp`
        if (window.screen.width > 600) {
          url = url.replace(/\.webp$/, '@2x.webp')
        }
        picture.value = new URL(url, import.meta.url).href
      }
    })

    return {
      iconClass,
      ElIconItem,
      AntIconItem,
      picture,
      color,
      iconRef,
      fontSize,
    }
  },
})
</script>

<style lang="scss" scoped>
@import '/iconfont/iconfont.css';

.icon {
  color: inherit;
  font-size: inherit;
}

.icon-picture {
  display: inline-flex;
  width: 1em;
  height: 1em;
  background-size: 0 0;
  background-repeat: no-repeat;
  background-position: center;
  line-height: inherit;
  overflow: hidden;

  > .icon-picture__shader {
    background: inherit;
    background-size: 100% 100%;
    display: block;
    height: 100%;
    width: 100%;
    transform: translateX(-100%);
  }
}
</style>
